use std::{fs, process::Command};

use serde::Deserialize;

#[derive(Deserialize, Debug)]
struct Data([[i32; 10]; 16]);

impl Data {
    pub fn clear(&mut self, x: usize, y: usize, w: usize, h: usize) {
        for i in 0..w {
            for j in 0..h {
                self.0[y + j][x + i] = 0
            }
        }
    }

    pub fn sum(&mut self, x: usize, y: usize, w: usize, h: usize) -> i32 {
        let mut res = 0;
        for i in 0..w {
            for j in 0..h {
                res += self.0[y + j][x + i];
            }
        }
        res
    }

    pub fn is_ten(&mut self, x: usize, y: usize, w: usize, h: usize) -> bool {
        self.sum(x, y, w, h) == 10
    }

    pub fn score(self) -> i32 {
        let mut s = 0;
        for i in self.0 {
            for y in i {
                if y == 0 {
                    s = s + 1;
                }
            }
        }
        s
    }
}

struct AdbCmd {
    dx: usize,
    dy: usize,
    x0: usize,
    y0: usize,
}

impl AdbCmd {
    pub fn new(point1: (usize, usize), point2: (usize, usize)) -> Self {
        let dx: usize = (point2.0 - point1.0) / 8;
        let dy = (point2.1 - point1.1) / 14;
        let x0 = point1.0 - dx / 2;
        let y0 = point1.1 - dy / 2;
        Self { dx, dy, x0, y0 }
    }

    pub fn cmd(&self, x: usize, y: usize, w: usize, h: usize) {
        let x1 = self.x0 + x * self.dx;
        let y1 = self.y0 + y * self.dy;
        let x2 = x1 + (w - 1) * self.dx;
        let y2 = y1 + (h - 1) * self.dy;
        Command::new("adb")
            .args(["shell", "input", "touchscreen", "swipe"])
            .args([
                format!("{x1}"),
                format!("{y1}"),
                format!("{x2}"),
                format!("{y2}"),
                "100".to_owned(),
            ])
            .output()
            .unwrap();
    }
}

fn main() {
    let point1: (usize, usize) = (150, 600);
    let point2 = (1050, 2170);
    let str2 = fs::read_to_string("../result.json").unwrap();
    let mut s = serde_json::from_str::<Data>(&str2).unwrap();
    let cmd = AdbCmd::new(point1, point2);
    for len in 3..26 {
        for w in 1..len {
            let h = len - w;
            // let (w, h) = (h, w);
            if w > 0 && w < 10 && h < 16 && h > 0 {
                for y in 0..(16 - h + 1) {
                    for x in 0..(10 - w + 1) {
                        if s.is_ten(x, y, w, h) {
                            cmd.cmd(x, y, w, h);
                            s.clear(x, y, w, h);
                        }
                    }
                }
            }
        }
    }
    for len in 3..26 {
        for w in 1..len {
            let h = len - w;
            // let (w, h) = (h, w);
            if w > 0 && w < 10 && h < 16 && h > 0 {
                for y in 0..(16 - h + 1) {
                    for x in 0..(10 - w + 1) {
                        if s.is_ten(x, y, w, h) {
                            cmd.cmd(x, y, w, h);
                            s.clear(x, y, w, h);
                        }
                    }
                }
            }
        }
    }
    for len in 3..26 {
        for w in 1..len {
            let h = len - w;
            // let (w, h) = (h, w);
            if w > 0 && w < 10 && h < 16 && h > 0 {
                for y in 0..(16 - h + 1) {
                    for x in 0..(10 - w + 1) {
                        if s.is_ten(x, y, w, h) {
                            cmd.cmd(x, y, w, h);
                            s.clear(x, y, w, h);
                        }
                    }
                }
            }
        }
    }

    let score = s.score();
    println!("score:{score}");
}
